package com.shijun.tankwar;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

/**
 * Created by zhushijun on 2018/1/12 0012.
 */

public class ControlMoveView extends View {
    public static final double π = Math.PI;
    private static final String TAG = "ControlMoveView";
    protected int startX;
    protected int startY;
    protected int currentX;
    protected int currentY;
    protected double MAXMOVEORIENTATION = π * (15d / 180d);//最大转角15度
    protected float tankOrientation = 0;
    public static final int TYPE_STOP = 0;
    public static final int TYPE_MOVE = 1;
    protected int x, y, width, height;
    protected double tankMoveOrientation;

    private OnTouchControlListener onTouchControlListener;

    public ControlMoveView(Context context, int x, int y, int width, int height) {
        super(context);
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
        initView();
    }

    private void initView() {
        startX = x + width / 2;
        startY = y + height / 2;
    }

    public ControlMoveView(Context context,  AttributeSet attrs) {
        super(context, attrs);
    }

    public ControlMoveView(Context context,  AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

//    public TankEntity getTankInfo() {
//        return tankInfo;
//    }
//
//    public void setTankInfo(TankEntity tankInfo) {
//        this.tankInfo = tankInfo;
//    }

    public void setOnTouchControlListener(OnTouchControlListener onTouchControlListener) {
        this.onTouchControlListener = onTouchControlListener;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_MOVE:
                currentX = (int) event.getX();
                currentY = (int) event.getY();
                if ((currentX - startX) * (currentX - startX) + (currentY - startY) * (currentY - startY) > (width / 4) * (width / 4)
                        && (currentX - startX) * (currentX - startX) + (currentY - startY) * (currentY - startY) < (width / 2) * (width / 2)) {
                    setBackgroundResource(R.mipmap.move_control_30);
                    double oldOrientation = tankOrientation * π / 180d;
                    double newOrientation = getOrientationByTwoPoint(startX, startY, (int) event.getX(), (int) event.getY());
                    float tankOrientation = (float) getOrientationOnMaxOrientationLimit(oldOrientation, newOrientation, MAXMOVEORIENTATION);
                    onTouchControlListener.onControl(tankMoveOrientation, tankOrientation, TYPE_MOVE);
                }
                break;
            case MotionEvent.ACTION_UP:
                Log.i(TAG,"ACTION_UP");
                setBackgroundResource(R.mipmap.move_control_10);

                onTouchControlListener.onControl(0, tankOrientation, TYPE_STOP);
                break;
        }
        return true;
    }

    protected double getOrientationByTwoPoint(int startX, int startY, int currentX, int currentY) {
        double newOrientation = 0;
        double disX = (currentX - startX);
        double disY = -(currentY - startY);
        if (disY == 0) {
            newOrientation = 0;
        } else if (disY > 0) {
            newOrientation = Math.atan2(disY, disX);
        } else {
            newOrientation = 2 * π + Math.atan2(disY, disX);
        }
        return newOrientation;
    }

    protected double getOrientationOnMaxOrientationLimit(double oldOrientation, double newOrientation, double maxMoveOrientation) {
        //如果分别在一四区间，需要把一区间的加上一个周期
        if (oldOrientation <= π * 0.5d && newOrientation >= π * 1.5d) {
            oldOrientation = oldOrientation + π * 2d;
        } else if (oldOrientation >= π * 1.5d && newOrientation <= π * 0.5d) {
            newOrientation = newOrientation + π * 2d;
        }

        double distanceOrientation = oldOrientation - newOrientation;
        boolean isTurnOrientation = false;
        if (Math.abs(distanceOrientation) >= π * 0.5d) {
            isTurnOrientation = true;
            if (newOrientation - π >= 0) {
                newOrientation = newOrientation - π;
            } else {
                newOrientation = newOrientation + π;
            }

            //位置变化，重新来一遍
            if (oldOrientation <= π * 0.5d && newOrientation >= π * 1.5d) {
                oldOrientation = oldOrientation + π * 2d;
            } else if (oldOrientation >= π * 1.5d && newOrientation <= π * 0.5d) {
                newOrientation = newOrientation + π * 2d;
            }
        }

        if (oldOrientation - newOrientation > maxMoveOrientation) {
            if (oldOrientation - maxMoveOrientation < 0) {
                newOrientation = (float) (π * 2d + (oldOrientation - maxMoveOrientation));
            } else if (oldOrientation - maxMoveOrientation > π * 2d) {
                newOrientation = (float) ((oldOrientation - maxMoveOrientation) - π * 2d);
            } else {
                newOrientation = (float) (oldOrientation - maxMoveOrientation);
            }
        } else if (oldOrientation - newOrientation < -maxMoveOrientation) {
            if (oldOrientation + maxMoveOrientation < 0) {
                newOrientation = (float) (π * 2d + (oldOrientation + maxMoveOrientation));
            } else if (oldOrientation + maxMoveOrientation > π * 2d) {
                newOrientation = (float) ((oldOrientation + maxMoveOrientation) - π * 2d);
            } else {
                newOrientation = (float) (oldOrientation + maxMoveOrientation);
            }
        }

        if (isTurnOrientation) {
            if (newOrientation - π >= 0) {
                tankMoveOrientation = newOrientation - π;
            } else {
                tankMoveOrientation = newOrientation + π;
            }
        } else {
            tankMoveOrientation = newOrientation;
        }
        tankOrientation = (float) ((newOrientation / π) * 180);
        return tankOrientation;
    }

    public interface OnTouchControlListener {
        void onControl(double tankMoveOrientation, float tankOrientation, int type);
    }
}
